An interactive 3D program needs a way to get input from the user. GLUT provides callback routines to be registered for each window for keyboard, mouse button, and mouse motion input.
glutKeyboardFunc(keyboard);This routine registers a callback for keyboard input for the current window. The function keyboard might be written like this:
void keyboard(unsigned char key, int x, int y) { printf("key `%c' pressed at (%d,%d)\n", key, x, y); }If the keyboard callback is registered for a window, the keyboard routine will be called when a key is pressed in the window. The ASCII character generated by the key press is passed in along with the location of the cursor within the window (relative to an origin at the upper left hand corner of the window).
glutMouseFunc(mouse); glutMotionFunc(motion);These routines register callbacks for mouse button changes and mouse motion (when buttons are down) for the current window. The following are example callbacks:
void mouse(int btn, int state, int x, int y) { printf("button %d is %s at (%d,%d)\n", btn, state == GLUT_DOWN ? "down" : "up", x, y); } void motion(int x, int y) { printf("button motion at (%d,%d)\n", x, y); }
The callbacks that can be registered with GLUT are not limited to input devices. The already introduced glutDisplayFunc routine lets you know when to redraw the window. The callback registered by glutReshapeFunc is called when a window is resized. A default handler exists for handling window resizes that calls glViewPort(0,0,w,h), where w and h are the new width and height of the window. This makes the entire window available for OpenGL rendering. Usually this is appropriate, but you can call glutReshapeFunc to specify your own reshape callback if necessary.
Also callbacks can be registered for timeouts and when the program is ``idling.'' A program doing continuous animation redraws each new scene as fast as the system will permit. This can be done by specifying an ``idle'' function using:
glutIdleFunc(idle);The function idle will be called whenever there is nothing else to do. If each time idle is called the program renders a new scene, the window is continuously animated. Event processing happens between calls to your idle function so be careful not to spend too much time in your idle function or you risk compromising your program's interactivity. There can be only one idle function registered at a time. If you call glutIdleFunc with NULL, the idle function is disabled. Idle callbacks are very much like X Toolkit work procedures.
glutVisibilityFunc(visibility)Because a program doing continuous animation is wasting its time if the window it is rendering into is completely obscured or unmapped, GLUT's glutVisibilityFunc routine registers a callback for the current window that is called when the window's visibility status changes. An example visibility callback:
void visibility(int status) { if(status == GLUT_VISIBLE) glutIdleFunc(animate); else /* stop animating */ glutIdleFunc(NULL); }
Another type of callback is the timer callback that is registered by calling glutTimerFunc like this:
glutTimerFunc(1000, timer, value);The first parameter indicates the number of milliseconds to wait before calling the timer callback function. The third parameter is an integer that will be passed to the timer callback. You can register multiple timer functions. Timer callbacks are very much like X Toolkit timeout callbacks.